﻿using Dapper;


using Dapper.Library;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Dapper.Library
{
    /// <summary>
    /// 实体类缓存帮助类
    /// </summary>
    public class EntityCache
    {
        internal static List<EntityObject> EntitieList = new List<EntityObject>();

        private static object lockObject = new object();

        /// <summary>
        /// 注册动态化查询可能会用到的实体类
        /// </summary>
        /// <param name="entity">实体类</param>
        public static EntityObject Register(Type entity, SqlProvider SqlProvider, IDbConnection dbCon = null)
        {
            EntityObject entityObject = new EntityObject(entity, SqlProvider, dbCon);
            lock (lockObject)
            {
                if (!EntitieList.Exists(p => p.AssemblyString.Equals(entityObject.AssemblyString)))
                {
                    SqlMapper.SetTypeMap(entityObject.Type, new CustomPropertyTypeMap(entityObject.Type,
                        (type, column) =>
                        type.GetPropertys(entityObject.FieldPairs.FirstOrDefault(x => x.Value.Equals(column)).Key)
                        ));

                    EntitieList.Add(entityObject);
                }
            }
            return entityObject;
        }

        /// <summary>
        /// 注册动态化查询可能会用到的实体类
        /// </summary>
        /// <param name="entitys">实体类</param>
        public static void Register(Type[] entitys, SqlProvider SqlProvider)
        {
            foreach (var item in entitys)
            {
                Register(item, SqlProvider);
            }
        }

        /// <summary>
        /// 注册动态化查询可能会用到的实体类
        /// </summary>
        /// <param name="assemblyString">通过给定程序集的长格式名称加载程序集。</param>
        public static void Register(string assemblyString, SqlProvider SqlProvider)
        {
#if !NETSTANDARD1_3
            Assembly assembly = Assembly.Load(assemblyString);
#else
            Assembly assembly = Assembly.Load(new AssemblyName(assemblyString));
#endif
            Register(assembly.GetTypes(), SqlProvider);
        }

        /// <summary>
        /// 查询实体类信息
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static EntityObject QueryEntity(Type entity, SqlProvider SqlProvider, IDbConnection dbCon = null)
        {
            var entityType = EntitieList.FirstOrDefault(x => x.Type.FullName.Equals(entity.FullName));
            if (entityType != null)
            {
                return entityType;
            }
            else
            {
                return Register(entity, SqlProvider, dbCon);
            }
        }

        /// <summary>
        /// 查询实体类信息（模糊查询）
        /// </summary>
        /// <param name="entityFullName"></param>
        /// <returns></returns>
        public static EntityObject QueryEntity(string entityFullName)
        {
            var entityType = EntitieList.FirstOrDefault(x => x.Type.FullName.Contains(entityFullName));
            return entityType;
        }

        /// <summary>
        /// 获取所有实体
        /// </summary>
        /// <returns></returns>
        public static List<EntityObject> GetEntities()
        {
            Type entityType;
            return EntitieList.Where(x => ExpressionExtension.IsAnyBaseEntity(x.Type, out entityType)).Distinct().ToList();
        }
    }
}
